package org.shangrila.app.sys.cfg;

/**
 * 系统配置和数据字典类
 */
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;

import javax.el.ELContext;
import javax.enterprise.context.ApplicationScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import javax.inject.Named;
import javax.servlet.http.HttpServletRequest;

import org.shangrila.app.sys.eo.SysDictitem;
import org.shangrila.bme.eo.AppLogInfo;
import org.shangrila.comm.dao.DbAccess;
import org.shangrila.comm.helper.IDHelper;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;

@Named
@ApplicationScoped
public class AppInitInfo {
	public static final String APP_VERSION_NO; 		//应用版本

	public static final String WFM_UPLOAD_FILE_PATH ;  //上传数据文件名在服务器的存储路径
	public static final String BME_UPLOAD_FILE_PATH ;  //上传数据文件名在服务器的存储路径
	public static final String VALIDATE_IMAGE_FILE_PATH  ;  //图片验证文件路径
	public static final String OS_SEPERATOR ; 
	public static final String WOS_SEPERATOR ; 

	public static final String APP_BUSINESS_NO="businessNo"; 		//WFM实例编号=业务编号
	public static final String APP_OPERATOR="operator";				//WFM下一个流程节点处理工号
	public static final String APP_BUSINESS_TYPE="businessType"; 	//WFM实例 自定义业务参数=业务类型

	public static final String PROCESS_WF_HTSH="wf_htsh"; 	//WFM流程
	public static final String PROCESS_WF_CGDD="wf_cgdd"; 	
	public static final String PROCESS_WF_FHD="wf_fhd"; 
	public static final String PROCESS_WF_YSDSH="wf_ysdsh"; 
	public static final String PROCESS_WF_HTBG="wf_htbgsq"; 
	
	
	//BMEPP 数据字典 
	private  static List<SysDictitem> ItemsDictItem;
	private  static DbAccess db = new DbAccess();
	
	static {
		ItemsDictItem = db.findEntityAll("SysDictitem"); //全部数据字典集合
		WFM_UPLOAD_FILE_PATH = getNameByCode("AppParas","WFM_UPLOAD_FILE_PATH");
		BME_UPLOAD_FILE_PATH = getNameByCode("AppParas","BME_UPLOAD_FILE_PATH");
		VALIDATE_IMAGE_FILE_PATH = getNameByCode("AppParas","VALIDATE_IMAGE_FILE_PATH");
		OS_SEPERATOR = getNameByCode("AppParas","OS_SEPERATOR");
		WOS_SEPERATOR = getNameByCode("AppParas","WOS_SEPERATOR");	
		APP_VERSION_NO = getNameByCode("AppInfo","VERSION");	
	}

	public String getVersion() {
		return APP_VERSION_NO;
	}
	
	// 提取数据字典数据
	public static List<SysDictitem> findSysDictitem() {		
		return ItemsDictItem;
	}
	// 刷新数据字典数据
	public static List<SysDictitem> refreshSysDictitem() {		
		ItemsDictItem = db.findEntityAll("SysDictitem");
		return ItemsDictItem;
	}

	/**
	 * 根据数据字典查找取值数据集合
	 * @param dictcode  数据字典名称
	 * @return
	 */
	public static Collection<SysDictitem> getDictcodeList(String dictcode) {			
		Collection<SysDictitem>  filterCollection = 
			       Collections2.filter(ItemsDictItem, new Predicate<SysDictitem>(){ 
			   @Override 
			   public boolean apply(SysDictitem input) { 
			       return dictcode.equalsIgnoreCase(input.getDictcode()); //返回符合条件的集合
			}});
		return filterCollection;	
	}
	/**
	 * 根据数据字典DICTCODE,CODE查找NAME(值)
	 * @param dictcode  数据字典名称
	 * @param code  数据code
	 * @return
	 */
	public static String getNameByCode(String dictcode,String code) {			
		Collection<SysDictitem>  dCollection =  getDictcodeList(dictcode);
		for(SysDictitem sd:dCollection) {
			if(code.equals(sd.getCode())){
				return sd.getName();
			}
		}
		return null;	
	}
	/**
	 * 根据数据字典DICTCODE查找NAME(值)
	 * @param dictcode  数据字典名称
	 * @return
	 */
	public static String getDictnameByDictcode(String dictcode) {			
		for(SysDictitem sd:ItemsDictItem) {
			if(dictcode.equals(sd.getDictcode())){
				return sd.getDictname();
			}
		};
		return null;	
	}	
	/**
	 * 根据数据字典查找取值数据集合：每次数据库方式
	 * @param dictcode  数据字典名称
	 * @return
	 */
	public static List<SysDictitem> findDropList(String dictcode) {
		String sql = "SELECT s FROM SysDictitem s WHERE s.dictcode=?1";
		return db.findBySql(sql, new Object[] {dictcode});
	}

	/**
	 * 获取JSF下拉式数据字典:从SysDictitem中获取制定字典dictcode的下拉清单
	 * 示例  AppInitInfo.getDropdownList("Msort");  //SysDictitems数据字典转换为下拉数据
	 * @param String dictcode
	 * @return
	 */	
	public static List<SelectItem> getDropdownList(String dictcode) {			
		
		List<SelectItem> dropList = new ArrayList<SelectItem>();		
		Iterator<SysDictitem> iterator = getDictcodeList(ItemsDictItem, dictcode).iterator();
		while(iterator.hasNext()) {
			SysDictitem sdi = iterator.next();
			dropList.add(new SelectItem(sdi.getCode(),sdi.getName()));
			//System.out.println(sdi.getCode()+"--"+sdi.getName());
		}
		return dropList;	
	}
	
	/**
	 * 获取JSF下拉式数据字典:从SysDictitem中获取制定字典dictcode的下拉清单
	 * 示例  AppInitInfo.getDropdownList("Msort","NULL");  //SysDictitems数据字典转换为下拉数据
	 * @param String dictcode
	 * @param String type
	 * @return
	 */
	public static List<SelectItem> getDropdownList(String dictcode,String type) {			
		
		List<SelectItem> dropList = new ArrayList<SelectItem>();		
		if (type.equalsIgnoreCase("NULL"))  //增加一个空选择
			dropList.add(new SelectItem(null, ""));
		else if (type.equalsIgnoreCase("ALL"))   //增加一个全部选择
			dropList.add(new SelectItem("0", "全部"));
		else if (type.equalsIgnoreCase("NONE")) ;  //什么都不加
		
		Iterator<SysDictitem> iterator = getDictcodeList(ItemsDictItem, dictcode).iterator();
		while(iterator.hasNext()) {
			SysDictitem sdi = iterator.next();
			dropList.add(new SelectItem(sdi.getCode(),sdi.getName()));
			//System.out.println(sdi.getCode()+"--"+sdi.getName());
		}
		return dropList;	
	}
	/**
	 * 从SysDictitem大集合中获取指定数据字典dictcode的集合：在大集合中查找
	 * @param List<SysDictitem> list
	 * @param dictcode
	 * @return
	 */
	public static Collection<SysDictitem> getDictcodeList(List<SysDictitem> list,String dictcode) {			
		Collection<SysDictitem>  filterCollection = 
			       Collections2.filter(list, new Predicate<SysDictitem>(){ 
			   @Override 
			   public boolean apply(SysDictitem input) { 
			       return dictcode.equalsIgnoreCase(input.getDictcode()); //返回符合条件的集合
			}});
		return filterCollection;	
	}
	
	/**
	 * 根据SQL查找结果转换成下拉式LIST
	 * 示例	AppInitInfo.getDropdownMap("BmeMaterial","id","mdesc");//实体BmeMaterial中数据id，mdesc直接转化成下拉数据
	 * @param String entityname
	 * @param String code
	 * @param String name
	 * @return List<SelectItem>
	 */
	public static List<SelectItem> getDropdownList(String entityname,String code,String name) {
		StringBuilder sql = new StringBuilder("SELECT ");
		sql.append(code+","+name);
		sql.append(" FROM ");
		sql.append(entityname);
		
		List<Object[]> olist = db.findPartBySql(sql.toString());
		List<SelectItem> dropList = new ArrayList<SelectItem>();	
		for(Object[] o : olist) {
			dropList.add(new SelectItem((String)o[0],(String) o[1]));
			//System.out.println(o[0]+"--"+o[1]);
		}
		return dropList;
	}
	
	/**
	 * 根据SQL查找结果转换成下拉式LIST
	 * 示例	AppInitInfo.getDropdownList("BmeMaterial","id","mdesc");//实体BmeMaterial中数据id，mdesc直接转化成下拉数据
	 * @param String entityname
	 * @param String code
	 * @param String name
	 * @return Map<String, String>
	 */    
    public static LinkedHashMap<String, String> getDropdownMap(String entityname,String code,String name) {
		StringBuilder sql = new StringBuilder("SELECT ");
		sql.append(code+","+name);
		sql.append(" FROM ");
		sql.append(entityname);
		LinkedHashMap<String,String> dpMpas = new LinkedHashMap<String, String>();
		//dpMpas.put("","");
    	List<Object[]> olist = db.findPartBySql(sql.toString());
    	for(Object[] o : olist) {
    		dpMpas.put((String)o[0],(String) o[1]);
			//System.out.println(o[0]+"--"+o[1]);
		}
        return dpMpas;
    }
    
	/**
	 * 【旧】通用数据下拉框 NULL ALL NONE 将List<SysDictitem>转化为JSF List<SelectItem>
	 * @param List<SysDictitem> dplist
	 * @param type
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static List<SelectItem> getDropdownList(List dplist,String type) {	

		List<SelectItem> dropList = new ArrayList<SelectItem>();
		dropList.clear();
		
		if (type.equalsIgnoreCase("NULL"))  //增加一个空选择
			dropList.add(new SelectItem(null, ""));
		else if (type.equalsIgnoreCase("ALL"))   //增加一个全部选择
			dropList.add(new SelectItem("0", "全部"));
		else if (type.equalsIgnoreCase("NONE")) ;  //什么都不加
					
		for (int i = 0; i < dplist.size(); i++)
			dropList.add(new SelectItem(
					((SysDictitem) (dplist.get(i))).getCode(),
					((SysDictitem) (dplist.get(i))).getName()));
		return dropList;	
	}
	
	/**
	 * 根据数据字典代码对应的显示名称code-name
	 * @param list
	 * @param code
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static String findNameByCode(List list,String code) {
		for (Object obj : list) {
			if (code.equalsIgnoreCase(((SysDictitem)obj).getCode())) {
				return ((SysDictitem)obj).getName();
			}
		}
		return code;
	}

	/**
	 * 根据数据字典代码对应的显示名称dictcode--dictname
	 * @param list
	 * @param code
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	public static String findDictnameByDictcode(List list,String code) {

		for (Object obj : list) {
			Object[] row  = (Object[])obj;			
			if (code.equalsIgnoreCase((String)row[0])) {
				return (String)row[1];
			}
		}
		return code;
	}
	
    /**
     * JSF中一个usingMB利用facescontext查找usedMB。
     * 获取后台Bean实例#{modelBean}： ModelBean 实例必须可以通过#{modelBean} 表达式得到
     * 示例:  BmeCustomerService s = (BmeCustomerService)AppInitInfo.findMBeanByName("bmeCustomerService",BmeCustomerService.class)
     * @param mbName
     * @param clazz
     * @return
     */
    @SuppressWarnings("unchecked")
	public static <T> T findMBeanByName(String mbName,Class<T> clazz) {
  	    ELContext elContext = FacesContext.getCurrentInstance().getELContext();
	    return (T) FacesContext.getCurrentInstance().getApplication().getExpressionFactory().createValueExpression(elContext,"#{"+mbName+"}",clazz).getValue(elContext);
    }

	/**
	 * JSF中一个usingMB利用facescontext查找usedMB，注意MB的范围不同
	 * @param name
	 * @return 
	 */
    @SuppressWarnings("unchecked")
	public static <T> T findSessionBeanByName(String name) {
       return (T) FacesContext.getCurrentInstance()
              .getExternalContext().getSessionMap().get(name);
    }
    @SuppressWarnings("unchecked")
	public static <T> T findApplicationBeanByName(String name) {
       return (T) FacesContext.getCurrentInstance()
              .getExternalContext().getApplicationMap().get(name);
    }
    @SuppressWarnings("unchecked")
	public static <T> T findRequestBeanByName(String name) {
       return (T) FacesContext.getCurrentInstance()
              .getExternalContext().getRequestMap().get(name);
    }
    
    /**
     * JSF 消息提示 
     * @param summary
     * @param detail
     */
	public static void showMessage(String summary, String detail) {
		FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO,summary, detail);
		FacesContext.getCurrentInstance().addMessage(null, message);
	}
    /**
     * JSF 消息提示 
     * @param info warn error fatal
     * @param summary
     * @param detail
     */
	public static void showMessage(String type,String summary, String detail) {
		FacesMessage message = null;
		if("into".equals(type))
			message = new FacesMessage(FacesMessage.SEVERITY_INFO,summary, detail);
		else if("warn".equals(type))
			message = new FacesMessage(FacesMessage.SEVERITY_WARN,summary, detail);
		else if("error".equals(type))
			message = new FacesMessage(FacesMessage.SEVERITY_ERROR,summary, detail);
		else if("fatal".equals(type))
			message = new FacesMessage(FacesMessage.SEVERITY_FATAL,summary, detail);
		else 
			message = new FacesMessage(FacesMessage.SEVERITY_INFO,summary, detail);

		FacesContext.getCurrentInstance().addMessage(null, message);
	}	
    /**
     * 应用日志记录 
     */
	public static AppLogInfo logAppLogInfo(String operNo,String operDesc,String busiDesc,String busiType,String busiNo,String funcButton,String funcDesc,String funcModule,String funcName,String keyAfter,String keyBefore,String remarks) {
		AppLogInfo ali = new AppLogInfo();

		ali.setBusiDesc(busiDesc);
		ali.setBusiType(busiType);
		ali.setBusiNo(busiNo);
		ali.setFuncButton(funcButton);
		ali.setFuncDesc(funcDesc);
		ali.setFuncModule(funcModule);
		ali.setFuncName(funcName);

		ali.setKeyAfter(keyAfter);
		ali.setKeyBefore(keyBefore);
		ali.setOperDesc(operDesc);
		ali.setOperNo(operNo);
		ali.setOperTime(new Date());
		ali.setRemarks(remarks);

		ali.setOperIp(((HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest()).getRemoteAddr());
		ali.setId(IDHelper.genStrID(24));
/*		
		db.beginTransaction();
		db.insert(ali);
		db.commitTransaction();
*/		
		return ali;
	}
	
	public static void main(String[] args) {
		
		/*
		String s=AppInitInfo.getDictnameByDictcode("AppParas");
		System.out.println(s);
		s=AppInitInfo.getNameByCode("AppParas","WFM_UPLOAD_FILE_PATH");
		System.out.println(s);
		
		
		Collection<SysDictitem> ls = AppInitInfo.getDictcodeList("AppParas");
		Iterator<SysDictitem> it = ls.iterator();
		while(it.hasNext()) {
			SysDictitem s = it.next();
			System.out.println(s.getCode()+"--"+s.getName());
		}
		*/
		//AppInitInfo.getDropdownList("Msort","NULL");  //SysDictitem数据字典转换为下拉数据
		//AppInitInfo.getDropdownList("BmeMaterial","id","mdesc");//实体BmeMaterial中数据id，mdesc直接转化成下拉数据
		//AppInitInfo.getDropdownMap("BmeMaterial","mdesc","mdesc");//实体BmeMaterial中数据id，mdesc直接转化成下拉数据
		
	}

}
